iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 6
0
Modern Web

什麼都略懂一點,生活更多彩一些。從web跑js出發到部屬heroku伺服器撈取API建構線上網站與LineBot系列 第 6

[day06][後端][學習] 現在,用express工具建立模版伺服器!(下)

  • 分享至 

  • xImage
  •  

同步發表到驢形筆記

前情提要

經過前兩篇的說明,應該對整個伺服器有一個大概的理解。接下來實際運用一下express建立自己的網站伺服器和簡單的API,實際跑過一次伺服器後,對於伺服器運作和如何修改成自己的網站伺服器應該就不是問題了。

下篇:express運用與建立基本API

經過前兩篇的流程和架構說明,對於伺服器的運作應該都能大概推論出來了吧。記得推論後實作非常重要,因為身為工程師誰沒跳錯誤會去看文件只有實際想過做過才能留下比較多的印象!

再次回到app.js,這邊要來處理所謂的middleware也就是中介層。中介層有非常多的可能性,可能的功能也非常的廣(可能是編譯檔案,可能是驗證資料,可能是獲取檔案...),可以自己實作也有許多相關套件可以用。簡單來說中介層非常不好理解,也很難簡單的推論,只能依靠經驗和實作理解。

還記得建立express時使用的指令嗎?不知道的可以回到day04看一下

express -v ejs -c sass

這邊-c sass是css的預處理器,一開始就可以不輸入也沒問題。現在如果不想使用的話,也只要把以下的程式碼砍掉就可以了

app.js

略
var sassMiddleware = require('node-sass-middleware');
略
app.use(sassMiddleware({
  src: path.join(__dirname, 'public'),
  dest: path.join(__dirname, 'public'),
  indentedSyntax: true, // true = .sass and false = .scss
  sourceMap: true
}));
略

然後到"package.json"把

package.json

    "node-sass-middleware": "0.11.0"

刪掉就可以了,但這畢竟是本篇唯一一個中介層。請試著使用看看。因為本次使用的scss基本上用css的寫法也通。且scss略懂系列也會帶到畢竟什麼都略懂一點,生活更多彩一些

讓我們回到程式碼。他說明了他會處理再"public"關於.sass結尾的所有檔案,請到"public\stylesheets"下看看,這時候應該會有三個檔案
https://ithelp.ithome.com.tw/upload/images/20200920/20130673hMz9uRH976.jpg
其中只有style.sass檔是主體檔案,另外兩個檔案是該中介層編譯後生出來的檔案(style.css是網頁讀取的檔案style.css.map是讓debugTool知道這個css對應到sass哪一行用的),而這個就是該中介層負責的工作,把在該資料夾下的sass轉譯成網頁看得懂的css。所以也可以單純在這邊撰寫css,並不是一定要使用css的預處理器!

現在,因為個人比較習慣撰寫scss所以依照已經存在的註釋對"indentedSyntax"進行調整

app.js

app.use(sassMiddleware({
  src: path.join(__dirname, 'public'),
  dest: path.join(__dirname, 'public'),
  indentedSyntax: false, // true = .sass and false = .scss
  sourceMap: true
}));

這樣伺服器就變成對該資料夾下的所有scss進行編譯了,所以也要修改該"style.sass"檔案名稱和內容。把.sass改成.scss然後內容改成以下

style.scss

body{
  padding: 50px;
  font: 60px "Lucida Grande", Helvetica, Arial, sans-serif;
}
a{
  color: #00B7FF;
}

目前看來跟css一模一樣對吧,但一個技術的出現一定是為了解決某些問題!這部分之後會進行學習,這邊就把他當成css吧

現在把除了style.scss之外的另外兩個檔案刪掉在開啟伺服器看看。開啟伺服器後你會看到這個資料夾沒有任何反應只是個scss,但只要連進(http://localhost:3000/ )後另外兩個檔案就突然出現了!這邊可以得到一個推測,該中介層發生的時間是在發生連線時觸發(注意這一點,中介層的發生時機點相當多樣性!所以非常不好理解)。好的,這個中介層到這邊就算是理解完成了!畢竟這算是簡單類型的中介層,功能也只是讓伺服器可以幫忙處理sass/scss檔案而已所以很好理解(當然這個套件已經涉及到檔案建立了實際上並不簡單)

接下來前往路由檔案"routes/index.js"修改title變數

routes/index.js

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: '什麼都略懂一點,生活更多彩一些' });
});

重新啟動伺服器連到(http://localhost:3000/ )
https://ithelp.ithome.com.tw/upload/images/20200920/20130673CWyaJcAwDg.jpg

可以看到標籤列和文字都已經更改了,這邊day05已經說明過了所以帶過。接下來要進行簡單的API呼叫,前往"views\index.ejs"

這邊可以直接複製,只是簡單的呼叫API
views\index.ejs

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    略
    <script>
        let callApiButton = document.getElementById('callApi');
        callApiButton.addEventListener('click',async function(){
          let result = await fetch('/users').then(res=>{
            return res.text();
          })
          alert(result);
        })
    </script>
  </body>
</html>

就能看到彈窗
https://ithelp.ithome.com.tw/upload/images/20200920/20130673nzOmT1CrOy.jpg

這邊的對於習慣在web跑js的人應該都不陌生,就是到這個網址(http://localhost:3000/users )去獲取資料。這邊運用之前在day05學過找路線的方法,應該可以找到這隻檔案"routes\users.js"。

routes\users.js

var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});
module.exports = router;

看到"respond with a resource"了嗎?這就是最簡單的"GET API"了,讓我們修改一下

routes\users.js

略
router.get('/', function(req, res, next) {
  res.send('Hello API');
});
略

然後重新啟動伺服器可以看到變化
https://ithelp.ithome.com.tw/upload/images/20200920/201306737J90E5R5HC.jpg
這樣一個簡單的API測試就完成囉

接下來就利用express已經有的架構實際建立一個分頁和POST API!實際運用看看,首先在"views\index.ejs"檔案加一個超連結

views\index.ejs

<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
    <button id="callApi">呼叫API</button>
    <a href="./test">前往新頁面</a>
略
    </script>
  </body>
</html>

在views資料夾新增一個檔案"test.ejs"並複製以下內容

views/test.ejs

<!DOCTYPE html>
<html>
  <head>
    <title>測試頁面</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1>這是測試頁面</h1>
    <p>Welcome to 這是測試頁面</p>
    <button id="callApi">呼叫API</button>
    <a href="./">前往首頁</a>
  </body>
</html>

最後前往路由為他建立一條路線(個人習慣吐頁面的統一寫在"routes\index.js"內)

routes\index.js

略
router.get('/test', function(req, res, next) {
  res.render('test');
});
略

重新啟動伺服器,這樣就有兩頁可以切換了!可以停下腳步觀察一下兩頁不同的地方,然後在繼續。

接下來要建立第一個post API。如果你並不熟悉get、post、patch和put等等的...可以先理解成他是一種跟伺服器交換東西的一種協定,在相同網址的情況因為協定的不同會由不同的路線觸發。現在在"routes"建立"test.js"檔案

routes\test.js

var express = require('express');
var router = express.Router();
router.post('/', function(req, res, next) {
  res.json({
    status: 'OK',
    value: 'hello post!建立好囉!'
  });
});
module.exports = router;

然後到app.js交出路線藍圖,記得要引入檔案

app.js

略
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var testRouter = require('./routes/test');
略
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/test', testRouter);
略

之後修改"views\test.ejs"的檔案,這邊可以直接複製

views\test.ejs

<!DOCTYPE html>
<html>
  <head>
    <title>測試頁面</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
略
    <script>
      let callApiButton = document.getElementById('callApi');
      callApiButton.addEventListener('click',async function(){
        let result = await fetch('/test',{
          method: 'post'
        }).then(res=>{
          return res.json();
        })
        alert(JSON.stringify(result));
      })
  </script>
  </body>
</html>

接下來到網頁(http://localhost:3000/test )呼叫API,就能看到你的第一個postAPI回傳的東西

https://ithelp.ithome.com.tw/upload/images/20200920/20130673AnGXY55Zp2.jpg

這樣今天的程式部分就算學習完成了,請在回頭看看routes這個資料夾下的所有檔案

應該會注意到以下三個res函式
res.render
res.json
res.send

並在路線藍圖上會發現test這條路同時存在get和post兩個協定。這個應該很好推測,因為協定不同所以沒有重複的問題

但上方的部分這邊進行講解。res是express提供的實例,裡面有許多express提供的方法。

  • render是告知遊覽器端要重新渲染畫面,並用哪一隻ejs檔案做渲染
  • json是告知遊覽器端我回傳的json檔
  • send可以理解成寄送string(我也很少用)

然後還有一個是

  • res.end() 告知遊覽器端處理好了

請記得這四種方法一定要選一個使用。不然遊覽器端會沒有辦法知道是不是該繼續等候伺服器回應這樣。因本系列是用希望略懂和能動為原則,有興趣的可以前往express尋找文件深入學習

那express相關的說明到這邊就講解完成,明天會學習如何實作API帶參數

githubday06


上一篇
[day05][後端][學習] 現在,用express工具建立模版伺服器!(中)
下一篇
[day07][後端][學習] API各種參數傳送與接收
系列文
什麼都略懂一點,生活更多彩一些。從web跑js出發到部屬heroku伺服器撈取API建構線上網站與LineBot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言